﻿'*******************************************************************************************
'* Copyright Brügmann Software GmbH, Papenburg
'* Author: Björn Kremer
'* Contact: codeplex<at>patorg.de
'* 
'* VB.CMIS is a VB.NET implementation of the Content Management Interoperability Services (CMIS) standard
'*
'* This file is part of VB.CMIS.
'* 
'* VB.CMIS is free software: you can redistribute it and/or modify
'* it under the terms of the GNU Lesser General Public License as published by
'* the Free Software Foundation, either version 3 of the License, or
'* (at your option) any later version.
'* 
'* VB.CMIS is distributed in the hope that it will be useful,
'* but WITHOUT ANY WARRANTY; without even the implied warranty of
'* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'* GNU Lesser General Public License for more details.
'* 
'* You should have received a copy of the GNU Lesser General Public License
'* along with VB.CMIS. If not, see <http://www.gnu.org/licenses/>.
'*******************************************************************************************
Imports System.ServiceModel.Web
Imports System.ServiceModel.Syndication
Imports System.ServiceModel
Imports System.Xml.Serialization
Imports CMISObjectModel.TypeDefinitions
Imports CMISObjectModel.ServiceDocument
Imports CMISObjectModel.Enums
Imports CMISObjectModel.Constants
Imports CMISObjectModel.CMISObjects
Imports CMISObjectModel.Atom
Imports CMISConnectorLibrary.Services.Interfaces
Imports CMISConnectorLibrary.Syndication.ServiceDocument
Imports CMISConnectorLibrary.Syndication

Namespace Services
   ''' <summary>
   ''' Implementation of all needed CMIS Functions. Please see: <see cref="CMISConnectorLibrary.Services.Interfaces.ICMISMainService" />
   ''' </summary>
   ''' <remarks></remarks>
   Public Class Service
      Implements ICMISMainService

      ''' <summary>
      ''' Uri of the CMIS service
      ''' </summary>
      ''' <value></value>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Public ReadOnly Property ServiceUri As Uri
         Get
            Dim oc As OperationContext = OperationContext.Current
            Return oc.EndpointDispatcher.EndpointAddress.Uri
         End Get
      End Property

      ''' <summary>
      ''' Current/Requested url.
      ''' </summary>
      ''' <value></value>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Public ReadOnly Property SelfLink As Uri
         Get
            Dim opContext = ServiceModel.OperationContext.Current
            Return opContext.IncomingMessageHeaders.To
         End Get
      End Property


      Public Function GetServiceDocuments() As AtomPub10ServiceDocumentFormatter Implements ICMISMainService.GetServiceDocuments
         Return GetServiceDocument(Nothing)
      End Function

      Public Function GetServiceDocument(repositoryId As String) As System.ServiceModel.Syndication.AtomPub10ServiceDocumentFormatter Implements ICMISMainService.GetServiceDocument
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim retVal As New CmisServiceDocument

         'If 'repositoryId' return a list off all repositories. Otherwise return the specified repository info.
         If String.IsNullOrEmpty(repositoryId) Then
            For Each repository As RepositoryInfo In ProviderManagerInstance.Provider.GetRepositories()
               'Repository info must be encapsulated by a CmisWorkspace object.
               retVal.Workspaces.Add(New CmisWorkspace(repository, ServiceUri))
            Next
         Else
            Dim repository As RepositoryInfo = ProviderManagerInstance.Provider.GetRepository(repositoryId)
            If repository Is Nothing Then
               Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
            End If
            'Repository info must be encapsulated by a CmisWorkspace object.
            retVal.Workspaces.Add(New CmisWorkspace(repository, ServiceUri))
         End If

         ctx.ContentType = CmisContentTypeConstants.Service
         Return DirectCast(retVal.GetFormatter, Global.System.ServiceModel.Syndication.AtomPub10ServiceDocumentFormatter)
      End Function

      Public Function ApplyACL(repositoryId As String, id As String, aclPropagation As String, rawData As Xml.XmlDocument) As Acl Implements ICMISMainService.ApplyACL
         Dim zACLPropagation As ACLPropagationEnum? = Common.ParseEnum(Of ACLPropagationEnum)(aclPropagation)
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         'Parse data
         Dim data As Acl = DirectCast(ParseReceiptCMISEntry(rawData), Acl)
         Dim result As Acl = ProviderManagerInstance.Provider.ApplyACL(repositoryId, id, zACLPropagation, rawData, data)
         If result Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         ctx.StatusCode = Net.HttpStatusCode.Created
         Return result
      End Function

      Public Function CheckOut(repositoryId As String, rawData As Xml.XmlDocument) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.CheckOut
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
        

         Dim data As CMISReceiptObject = DirectCast(ParseReceiptCMISEntry(rawData), CMISReceiptObject)

         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.CheckOut(repositoryId, rawData, data)
         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         'Sets the location of the returned document
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", cmisObject.Object.Id).TrimStart("/"c))


         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))

         ctx.Location = uri.AbsoluteUri
         ctx.ContentType = CmisContentTypeConstants.Entry
         ctx.StatusCode = Net.HttpStatusCode.Created

         Return New Atom10ItemFormatter(entry)
      End Function

      Public Sub DeleteAllVersions(repositoryId As String, id As String) Implements ICMISMainService.DeleteAllVersions
         DeleteObject(repositoryId, id, "true")
      End Sub

      Public Sub DeleteContentStream(repositoryId As String, id As String) Implements ICMISMainService.DeleteContentStream
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse

         ProviderManagerInstance.Provider.DeleteContentStream(repositoryId, id)
         ctx.StatusCode = Net.HttpStatusCode.NoContent
      End Sub

      Public Sub DeleteObject(repositoryId As String, id As String, allVersions As String) Implements ICMISMainService.DeleteObject
         Dim zAllVersions As Boolean? = Common.ParseBoolean(allVersions)
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse

         ProviderManagerInstance.Provider.DeleteObject(repositoryId, id, zAllVersions)
         ctx.StatusCode = Net.HttpStatusCode.NoContent
      End Sub

      Public Sub DeleteTree(repositoryId As String, id As String, allVersions As String, continueOnFailure As String, unfileObjects As String) Implements ICMISMainService.DeleteTree
         Dim zContinueOnFailure As Boolean? = Common.ParseBoolean(continueOnFailure)
         Dim zAllVersions As Boolean? = Common.ParseBoolean(allVersions)
         Dim zUnfileObjects As UnfileObjectsEnum? = Common.ParseEnum(Of UnfileObjectsEnum)(unfileObjects)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse

         Dim result As DeleteTreeResultEnum = ProviderManagerInstance.Provider.DeleteTree(repositoryId, id, zAllVersions, zContinueOnFailure, zUnfileObjects)
         'Set status code defined by the data provider.
         Select Case result
            Case DeleteTreeResultEnum.Ok
               ctx.StatusCode = Net.HttpStatusCode.OK
            Case DeleteTreeResultEnum.Accepted
               ctx.StatusCode = Net.HttpStatusCode.Accepted
            Case DeleteTreeResultEnum.NoContent
               ctx.StatusCode = Net.HttpStatusCode.NoContent
         End Select

      End Sub

      Public Function GetACL(repositoryId As String, id As String) As Acl Implements ICMISMainService.GetACL
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim acl As Acl = ProviderManagerInstance.Provider.GetACL(repositoryId, id)
         If acl Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         ctx.ContentType = CmisContentTypeConstants.Acl
         Return acl
      End Function

      Public Function GetAllVersions(repositoryId As String, id As String, filter As String, includeAllowableActions As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetAllVersions

         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)


         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetAllVersions(repositoryId, id, filter, zIncludeAllowableActions)
         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         'Adds additional atomlinks defined by the cmis standard.
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         links.Add(CmisSyndicationFeed.GetViaLink(uri))

         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), links)
         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function GetCheckedOutDocs(repositoryId As String, id As String, filter As String, maxItems As String, skipCount As String, renditionFilter As String, includeAllowableActions As String, includeRelationships As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetCheckedOutDocs
         Dim zMaxItems As Integer? = Common.ParseInt(maxItems)
         Dim zSkipCount As Integer? = Common.ParseInt(skipCount)
         Dim zIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)
         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)

         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetCheckedOutDocs(repositoryId, id, filter, zMaxItems, zSkipCount, renditionFilter, zIncludeAllowableActions, zIncludeRelationships)

         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         'Adds additional atomlinks defined by the cmis standard.
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         links.Add(CmisSyndicationFeed.GetViaLink(uri))
         links.AddRange(GetNavigationLinks(objects.Entries.Count, objects.TotalItemCount, objects.HasMoreItems, zSkipCount, zMaxItems))

         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), links)

         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function GetContentChanges(repositoryId As String, filter As String, maxItems As String, includeACL As String, includePolicyIds As String, includeProperties As String, changeLogToken As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetContentChanges
         Dim zIncludePolicyIds As Boolean? = Common.ParseBoolean(includePolicyIds)
         Dim zIncludeAcl As Boolean? = Common.ParseBoolean(includeACL)
         Dim zMaxItems As Integer? = Common.ParseInt(includeACL)
         Dim zIncludeProperties As Boolean? = Common.ParseBoolean(includeProperties)
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse



         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetContentChanges(repositoryId, filter, zMaxItems, zIncludeAcl, zIncludePolicyIds, zIncludeProperties, changeLogToken)

         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), GetBaseLinks(CmisContentTypeConstants.Feed))

         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function GetContentStream(repositoryId As String, id As String, streamId As String) As System.IO.Stream Implements ICMISMainService.GetContentStream
         Dim data As ContentStreamWrapper = ProviderManagerInstance.Provider.GetContentStream(repositoryId, id, streamId)
         If data Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Set the mimetype of the return value
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
         ctx.ContentType = data.MimeType
         Return data.Data
      End Function

      Public Function GetDescendants(repositoryId As String, id As String, filter As String, depth As String, includeAllowableActions As String, includeRelationships As String, renditionFilter As String, includePathSegment As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetDescendants
         Dim zDepth As Integer? = Common.ParseInt(depth)
         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)
         Dim zIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)
         Dim zIncludePathSegments As Boolean? = Common.ParseBoolean(includePathSegment)


         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetDescendants(repositoryId, id, filter, zDepth, zIncludeAllowableActions, zIncludeRelationships, renditionFilter, zIncludePathSegments)
         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         If Not String.IsNullOrEmpty(id) Then
            'Adds additional atomlinks defined by the cmis standard.
            Dim children As New Uri(ServiceUri, ServiceURIs.GetChildrenBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            Dim parent As New Uri(ServiceUri, ServiceURIs.GetObjectParentsBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            Dim tree As New Uri(ServiceUri, ServiceURIs.GetFolderTreeBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))


            links.Add(CmisSyndicationFeed.GetViaLink(uri))
            links.Add(CmisSyndicationFeed.GetDownLink(children))
            links.Add(CmisSyndicationFeed.GetUpLink(parent, CmisContentTypeConstants.Feed))
            links.Add(CmisSyndicationFeed.GetFolderTreeLink(tree))

         Else
            Dim children As New Uri(ServiceUri, ServiceURIs.GetChildrenBase.Replace("{repositoryId}", repositoryId).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetDownLink(children))
         End If

         Dim feed As New CmisSyndicationFeed(objects, True, ServiceUri, RepositoryInfo(repositoryId), links)
         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function GetFolderTree(repositoryId As String, id As String, filter As String, depth As String, includeAllowableActions As String, includeRelationships As String, renditionFilter As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetFolderTree
         Dim zDepth As Integer? = Common.ParseInt(depth)
         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)
         Dim zIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetFolderTree(repositoryId, id, filter, zDepth, zIncludeAllowableActions, zIncludeRelationships, renditionFilter)
         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If



         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         If Not String.IsNullOrEmpty(id) Then

            Dim children As New Uri(ServiceUri, ServiceURIs.GetChildrenBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            Dim parent As New Uri(ServiceUri, ServiceURIs.GetObjectParentsBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))


            links.Add(CmisSyndicationFeed.GetViaLink(uri))
            links.Add(CmisSyndicationFeed.GetDownLink(children))
            links.Add(CmisSyndicationFeed.GetUpLink(parent, CmisContentTypeConstants.Feed))


         Else
            Dim children As New Uri(ServiceUri, ServiceURIs.GetChildrenBase.Replace("{repositoryId}", repositoryId).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetDownLink(children))
         End If


         Dim feed As New CmisSyndicationFeed(objects, True, ServiceUri, RepositoryInfo(repositoryId), links)
         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function GetObject(repositoryId As String, id As String, pwc As String, returnVersion As String, includeAllowableActions As String, includeRelationships As String, includePolicyIds As String, includeACL As String, filter As String, renditionFilter As String) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.GetObject
         Dim pIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)
         Dim pIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)
         Dim pIncludePolicyIds As Boolean? = Common.ParseBoolean(includePolicyIds)
         Dim pIncludeAcl As Boolean? = Common.ParseBoolean(includeACL)
         Dim pPwc As Boolean? = Common.ParseBoolean(pwc)
         Dim zReturnVersion As ReturnVersionEnum? = Common.ParseEnum(Of ReturnVersionEnum)(returnVersion)
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse



         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.GetObject(repositoryId, id, pPwc, zReturnVersion, filter, pIncludeAllowableActions, pIncludeRelationships, renditionFilter, _
          pIncludePolicyIds, pIncludeAcl)

         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))

         ctx.ContentType = CmisContentTypeConstants.Entry
         Return New Atom10ItemFormatter(entry)
      End Function


      Public Function GetObjectByPath(repositoryId As String, path As String, filter As String, includeAllowableActions As String, includePolicyIds As String, includeRelationships As String, includeACL As String, renditionFilter As String) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.GetObjectByPath
         Dim pIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)
         Dim pIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)
         Dim pIncludePolicyIds As Boolean? = Common.ParseBoolean(includePolicyIds)
         Dim pIncludeAcl As Boolean? = Common.ParseBoolean(includeACL)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse



         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.GetObjectByPath(repositoryId, path, filter, pIncludeAllowableActions, pIncludeRelationships, renditionFilter, pIncludePolicyIds, pIncludeAcl)

         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))

         ctx.ContentType = CmisContentTypeConstants.Entry
         Return New Atom10ItemFormatter(entry)
      End Function

      Public Function GetObjectParents(repositoryId As String, id As String, filter As String, includeAllowableActions As String, includeRelationships As String, renditionFilter As String, includeRelativePathSegment As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetObjectParents
         Dim zIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)
         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)
         Dim zIncludeRelativePathSegment As Boolean? = Common.ParseBoolean(includeRelativePathSegment)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetObjectParents(repositoryId, id, filter, zIncludeRelationships, renditionFilter, zIncludeAllowableActions, zIncludeRelativePathSegment)

         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Adds additional atomlinks defined by the cmis standard.
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         links.Add(CmisSyndicationFeed.GetViaLink(uri))

         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), links)

         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)

      End Function

      Public Function GetTypeChildren(repositoryId As String, id As String, includePropertyDefinitions As String, maxItems As String, skipCount As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetTypeChildren
         Dim zMaxItems As Integer? = Common.ParseInt(maxItems)
         Dim zSkipCount As Integer? = Common.ParseInt(skipCount)
         Dim zIncludePropertyDefinitions As Boolean? = Common.ParseBoolean(includePropertyDefinitions)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse



         Dim typeList As CMISAtomFeed(Of TypeDefinition) = ProviderManagerInstance.Provider.GetTypeChildren(repositoryId, id, zIncludePropertyDefinitions, zMaxItems, zSkipCount)
         If typeList Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         links.AddRange(GetNavigationLinks(typeList.Entries.Count, typeList.TotalItemCount, typeList.HasMoreItems, zSkipCount, zMaxItems))
         If Not String.IsNullOrEmpty(id) Then
            Dim uri As New Uri(ServiceUri, ServiceURIs.GetTypeDefinition.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetViaLink(uri))

            Dim down As New Uri(ServiceUri, ServiceURIs.GetTypeDescendantsBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetDownDescLink(down))

            Dim parentId As String = ProviderManagerInstance.Provider.GetTypeParentId(repositoryId, id)
            If Not String.IsNullOrEmpty(parentId) Then
               Dim up As New Uri(ServiceUri, ServiceURIs.GetTypeChildrenBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", parentId).TrimStart("/"c))
               links.Add(CmisSyndicationFeed.GetUpLink(up, CmisContentTypeConstants.Entry))
            End If
         End If

         Dim feed As New CmisSyndicationFeed(typeList, False, ServiceUri, repositoryId, links)

         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function


      Public Function GetTypeDefinition(repositoryId As String, id As String) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.GetTypeDefinition
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim type As CMISAtomEntry(Of TypeDefinition) = ProviderManagerInstance.Provider.GetTypeDefinition(repositoryId, id)
         If type Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         Dim item As CmisSyndicationItem = New CmisSyndicationItem(type, ServiceUri, repositoryId)

         ctx.ContentType = CmisContentTypeConstants.Entry
         Return New Atom10ItemFormatter(item)
      End Function

      Public Function GetTypeDescendants(repositoryId As String, id As String, includePropertyDefinitions As String, depth As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetTypeDescendants
         Dim zDepth As Integer? = Common.ParseInt(depth)
         Dim zIncludePropertyDefinitions As Boolean? = Common.ParseBoolean(includePropertyDefinitions)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of TypeDefinition) = ProviderManagerInstance.Provider.GetTypeDescendants(repositoryId, id, zIncludePropertyDefinitions, zDepth)
         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         If Not String.IsNullOrEmpty(id) Then

            Dim children As New Uri(ServiceUri, ServiceURIs.GetTypeChildrenBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            Dim uri As New Uri(ServiceUri, ServiceURIs.GetTypeDefinition.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))

            links.Add(CmisSyndicationFeed.GetViaLink(uri))
            links.Add(CmisSyndicationFeed.GetDownLink(children))
            Dim parentId As String = ProviderManagerInstance.Provider.GetTypeParentId(repositoryId, id)
            If Not String.IsNullOrEmpty(parentId) Then

               Dim parent As New Uri(ServiceUri, ServiceURIs.GetTypeDefinition.Replace("{repositoryId}", repositoryId).Replace("{id}", parentId).TrimStart("/"c))
               links.Add(CmisSyndicationFeed.GetUpLink(parent, CmisContentTypeConstants.Entry))
            End If
         Else
            Dim children As New Uri(ServiceUri, ServiceURIs.GetTypeChildrenBase.Replace("{repositoryId}", repositoryId).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetDownLink(children))
         End If

         Dim feed As New CmisSyndicationFeed(objects, True, ServiceUri, repositoryId, links)
         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function Query(repositoryId As String, rawData As Xml.XmlDocument) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.QueryPost
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
        


         Dim data As Query = DirectCast(ParseReceiptCMISEntry(rawData, True), Query)

         'Sets the location header for the Query. The header points to the GET implementation of the query function.
         If data IsNot Nothing Then
            Dim queryLink As String = ServiceURIs.Query.Replace("{repositoryId}", repositoryId).TrimStart("/"c)

            queryLink = queryLink.Replace("{q}", System.Web.HttpUtility.UrlEncode(data.Statement))
            queryLink = queryLink.Replace("{searchAllVersions}", data.SearchAllVersions.ToString)
            queryLink = queryLink.Replace("{includeAllowableActions}", data.IncludeAllowableActions.ToString)
            queryLink = queryLink.Replace("{includeRelationships}", CMISObjectModel.Common.GetDataMemberValueFromEnum(data.IncludeRelationships, GetType(Enums.IncludeRelationships)))
            queryLink = queryLink.Replace("{maxItems}", data.MaxItems.ToString)
            queryLink = queryLink.Replace("{skipCount}", data.SkipCount.ToString)
            Dim queryLinkUri As New Uri(ServiceUri, queryLink)
            ctx.Location = queryLinkUri.AbsoluteUri
            ctx.Headers.Add("Content-Location", queryLinkUri.AbsoluteUri)
         End If



         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.Query(repositoryId, rawData, data)
         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         Dim feed As New CmisSyndicationFeed(objects, True, ServiceUri, RepositoryInfo(repositoryId), GetBaseLinks(CmisContentTypeConstants.Feed))
         ctx.ContentType = CmisContentTypeConstants.Feed
         ctx.StatusCode = Net.HttpStatusCode.Created
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function Query(repositoryId As String, q As String, searchAllVersions As String, maxItems As String, skipCount As String, includeAllowableActions As String, includeRelationships As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.QueryGet
         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)
         Dim zIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)
         Dim zMaxItems As Integer? = Common.ParseInt(maxItems)
         Dim zSkipCount As Integer? = Common.ParseInt(skipCount)
         Dim zSearchAllVersions As Boolean? = Common.ParseBoolean(searchAllVersions)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.Query(repositoryId, q, zSearchAllVersions, zMaxItems, zSkipCount, zIncludeAllowableActions, zIncludeRelationships)
         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)

         links.AddRange(GetNavigationLinks(objects.Entries.Count, objects.TotalItemCount, objects.HasMoreItems, zSkipCount, zMaxItems))
         Dim feed As New CmisSyndicationFeed(objects, True, ServiceUri, RepositoryInfo(repositoryId), links)
         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function RemoveObjectFromFolder(repositoryId As String, removeFrom As String, rawData As Xml.XmlDocument) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.RemoveObjectFromFolder
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
        

         Dim data As CMISObjects.CMISReceiptObject = DirectCast(ParseReceiptCMISEntry(rawData), CMISReceiptObject)

         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.RemoveObjectFromFolder(repositoryId, removeFrom, rawData, data)
         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Sets the location of the removed document
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", cmisObject.Object.Id).TrimStart("/"c))
         ctx.Location = uri.AbsoluteUri

         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))
         ctx.ContentType = CmisContentTypeConstants.Entry
         ctx.StatusCode = Net.HttpStatusCode.Created
         Return New Atom10ItemFormatter(entry)
      End Function

      Public Sub SetContentStream(repositoryId As String, id As String, overwriteFlag As String, data As System.IO.Stream) Implements ICMISMainService.SetContentStream
         Dim zOverwriteFlag As Boolean? = Common.ParseBoolean(overwriteFlag)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse

         Dim result As SetContentStreamResultEnum = ProviderManagerInstance.Provider.SetContentStream(repositoryId, id, zOverwriteFlag, data)
         'Set the status code defined by the data provider.
         Select Case result
            Case SetContentStreamResultEnum.HasContent
               ctx.StatusCode = Net.HttpStatusCode.OK
            Case SetContentStreamResultEnum.HasNoContent
               ctx.StatusCode = Net.HttpStatusCode.NoContent
            Case SetContentStreamResultEnum.ResourceCreated
               ctx.StatusCode = Net.HttpStatusCode.Created
         End Select

         'Location of the new content stream.
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetContentStreamBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
         ctx.Location = uri.AbsoluteUri
         ctx.Headers.Add("Content-Location", uri.AbsoluteUri)
      End Sub

      Public Function UpdateProperties(repositoryId As String, id As String, major As String, checkIn As String, checkinComment As String, rawData As Xml.XmlDocument) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.UpdateProperties
         Dim zMajor As Boolean? = Common.ParseBoolean(major)
         Dim zCheckIn As Boolean? = Common.ParseBoolean(checkIn)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
        

         Dim data As CMISObjects.CMISReceiptObject = DirectCast(ParseReceiptCMISEntry(rawData), CMISReceiptObject)

         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.UpdateProperties(repositoryId, id, zMajor, zCheckIn, checkinComment, rawData, data)
         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Location of the changed document
         If Not id.Equals(cmisObject.Object.Id) Then
            Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", cmisObject.Object.Id).TrimStart("/"c))
            ctx.Location = uri.AbsoluteUri
         End If
         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))
         ctx.ContentType = CmisContentTypeConstants.Entry
         ctx.StatusCode = Net.HttpStatusCode.OK
         Return New Atom10ItemFormatter(entry)
      End Function



      Public Function CreateOrMoveObject(repositoryId As String, id As String, sourceFolderId As String, versioningState As String, rawData As Xml.XmlDocument) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.CreateOrMoveObject
         Dim zVersioningState As VersioningStateEnum? = Common.ParseEnum(Of VersioningStateEnum)(versioningState)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
       

         Dim data As CMISObjects.CMISReceiptObject = DirectCast(ParseReceiptCMISEntry(rawData), CMISReceiptObject)
         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.CreateOrMoveObject(repositoryId, id, sourceFolderId, zVersioningState, rawData, data)
         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", cmisObject.Object.Id).TrimStart("/"c))


         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))
         ctx.Location = uri.AbsoluteUri
         ctx.ContentType = CmisContentTypeConstants.Entry
         ctx.StatusCode = Net.HttpStatusCode.Created
         Return New Atom10ItemFormatter(entry)
      End Function

      Public Function GetChildren(repositoryId As String, id As String, maxItems As String, skipCount As String, filter As String, includeAllowableActions As String, includeRelationships As String, renditionFilter As String, orderBy As String, includePathSegment As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetChildren
         Dim zMaxItems As Integer? = Common.ParseInt(maxItems)
         Dim zSkipCount As Integer? = Common.ParseInt(skipCount)
         Dim zIncludeRelationships As IncludeRelationships? = Common.ParseEnum(Of IncludeRelationships)(includeRelationships)
         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)
         Dim zIncludePathSegment As Boolean? = Common.ParseBoolean(includePathSegment)

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetChildren(repositoryId, id, zMaxItems, zSkipCount, orderBy, filter, _
          zIncludeRelationships, renditionFilter, zIncludeAllowableActions, zIncludePathSegment)

         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         links.AddRange(GetNavigationLinks(objects.Entries.Count, objects.TotalItemCount, objects.HasMoreItems, zSkipCount, zMaxItems))

         If Not String.IsNullOrEmpty(id) Then
            Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetViaLink(uri))

            Dim down As New Uri(ServiceUri, ServiceURIs.GetDescendantsBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetDownDescLink(down))

            Dim up As New Uri(ServiceUri, ServiceURIs.GetObjectParentsBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
            links.Add(CmisSyndicationFeed.GetUpLink(up, CmisContentTypeConstants.Entry))

            If RepositoryInfo(repositoryId).Capabilities.GetFolderTree Then
               Dim tree As New Uri(ServiceUri, ServiceURIs.GetFolderTreeBase1.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
               links.Add(CmisSyndicationFeed.GetFolderTreeLink(tree))
            End If

         End If

         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), links)

         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function GetAllowableActions(repositoryId As String, id As String) As AllowableActions Implements ICMISMainService.GetAllowableActions
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse

         Dim action As CMISObjectModel.CMISObjects.AllowableActions = ProviderManagerInstance.Provider.GetAllowableActions(repositoryId, id)
         ctx.ContentType = CmisContentTypeConstants.AllowableActions
         Return action
      End Function

      Public Function GetAppliedPolicies(repositoryId As String, id As String, filter As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetAppliedPolicies
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetAppliedPolicies(repositoryId, id, filter)

         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Adds additional atomlinks defined by the cmis standard.
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", id).TrimStart("/"c))
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         links.Add(CmisSyndicationFeed.GetViaLink(uri))
         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), links)

         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function
     
      Public Sub RemovePolicy(repositoryId As String, id As String) Implements ICMISMainService.RemovePolicy

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse

         ProviderManagerInstance.Provider.RemovePolicy(repositoryId, id)
         ctx.StatusCode = Net.HttpStatusCode.OK
      End Sub

      Public Function ApplyPolicy(repositoryId As String, id As String, rawData As Xml.XmlDocument) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.ApplyPolicy
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
       
         Dim data As CMISObjects.CMISReceiptObject = DirectCast(ParseReceiptCMISEntry(rawData), CMISReceiptObject)

         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.ApplyPolicy(repositoryId, id, rawData, data)
         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Location of the applied policy
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", cmisObject.Object.Id).TrimStart("/"c))


         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))
         ctx.Headers.Add("Content-Location", uri.AbsoluteUri)
         ctx.ContentType = CmisContentTypeConstants.Entry
         ctx.StatusCode = Net.HttpStatusCode.Created
         Return New Atom10ItemFormatter(entry)
      End Function

      Public Function CreateRelationship(repositoryId As String, id As String, rawData As Xml.XmlDocument) As System.ServiceModel.Syndication.Atom10ItemFormatter Implements ICMISMainService.CreateRelationship
         'Set default status code.
         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse
        

         Dim data As CMISObjects.CMISReceiptObject = DirectCast(ParseReceiptCMISEntry(rawData), CMISReceiptObject)

         Dim cmisObject As CMISAtomEntryCmisObject = ProviderManagerInstance.Provider.CreateRelationship(repositoryId, id, rawData, data)
         If cmisObject Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If
         'Location of the created relationship
         Dim uri As New Uri(ServiceUri, ServiceURIs.GetObjectBase.Replace("{repositoryId}", repositoryId).Replace("{id}", cmisObject.Object.Id).TrimStart("/"c))


         Dim entry As CmisSyndicationItem = New CmisSyndicationItem(cmisObject, ServiceUri, RepositoryInfo(repositoryId))

         ctx.Location = uri.AbsoluteUri
         ctx.ContentType = CmisContentTypeConstants.Entry
         ctx.StatusCode = Net.HttpStatusCode.Created

         Return New Atom10ItemFormatter(entry)
      End Function

      Public Function GetObjectRelationships(repositoryId As String, id As String, typeId As String, includeSubRelationshipTypes As String, relationshipDirection As String, maxItems As String, skipCount As String, filter As String, includeAllowableActions As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements ICMISMainService.GetObjectRelationships

         Dim zIncludeSubRelationshipTypes As Boolean? = Common.ParseBoolean(includeSubRelationshipTypes)
         Dim zRelationshipDirection As RelationshipDirectionEnum? = Common.ParseEnum(Of RelationshipDirectionEnum)(relationshipDirection)
         Dim zMaxItems As Integer? = Common.ParseInt(maxItems)
         Dim zSkipCount As Integer? = Common.ParseInt(skipCount)
         Dim zIncludeAllowableActions As Boolean? = Common.ParseBoolean(includeAllowableActions)


         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetObjectRelationships(repositoryId, id, typeId, zIncludeSubRelationshipTypes, zRelationshipDirection, zMaxItems, zSkipCount, filter, zIncludeAllowableActions)

         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)
         links.AddRange(GetNavigationLinks(objects.Entries.Count, objects.TotalItemCount, objects.HasMoreItems, zSkipCount, zMaxItems))
         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), links)

         ctx.ContentType = CmisContentTypeConstants.Feed
         Return New Atom10FeedFormatter(feed)
      End Function

      Public Function GetUnfiled(repositoryId As String) As System.ServiceModel.Syndication.Atom10FeedFormatter Implements Interfaces.ICMISMainService.GetUnfiled

         Dim ctx As OutgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse


         Dim objects As CMISAtomFeed(Of CmisObject) = ProviderManagerInstance.Provider.GetUnfiled(repositoryId)
         If objects Is Nothing Then
            Throw New WebFaultException(Net.HttpStatusCode.BadRequest)
         End If

         'Adds additional atomlinks defined by the cmis standard.
         Dim links As List(Of SyndicationLink) = GetBaseLinks(CmisContentTypeConstants.Feed)

         Dim feed As New CmisSyndicationFeed(objects, False, ServiceUri, RepositoryInfo(repositoryId), links)

         ctx.ContentType = CmisContentTypeConstants.Feed

         Return New Atom10FeedFormatter(feed)
      End Function

#Region "Interne Funktionen"
      ''' <summary>
      ''' Cache for RepositoryInfo objects. 
      ''' </summary>
      ''' <remarks></remarks>
      Private Shared _repInfo As New System.Runtime.Caching.MemoryCache(Guid.NewGuid.ToString)

      ''' <summary>
      ''' Returns the RepositoryInfo for the specified repository id.
      ''' </summary>
      ''' <param name="id"></param>
      ''' <value></value>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Private ReadOnly Property RepositoryInfo(id As String) As CMISObjectModel.ServiceDocument.RepositoryInfo
         Get
            'If caching is enabled cache the RepositoryInfo between the requests.
            If Common.DoCaching Then
               Dim retVal As CMISObjectModel.ServiceDocument.RepositoryInfo = Nothing
               'Check if id is in the cache.
               If _repInfo.Contains(id) Then
                  'Return cached object.
                  retVal = DirectCast(_repInfo.Get(id), CMISObjectModel.ServiceDocument.RepositoryInfo)
                  If retVal IsNot Nothing Then
                     Return retVal
                  End If
               End If
               'Request new RepositoryInfo and add it to cache.
               retVal = ProviderManagerInstance.Provider.GetRepository(id)
               _repInfo.AddOrGetExisting(id, retVal, Now.AddMinutes(5))
               Return retVal
            Else
               Return ProviderManagerInstance.Provider.GetRepository(id)
            End If
         End Get
      End Property

      ''' <summary>
      ''' This function parses the data sent by the client.
      ''' </summary>
      ''' <param name="rawData"></param>
      ''' <param name="force"></param>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Private Function ParseReceiptCMISEntry(rawData As Xml.XmlDocument, Optional force As Boolean = False) As Object
         Try
            'Check if parsing is enabled
            If Common.ParseData OrElse force Then
               'Check if data is base64 encoded
               rawData = CMISObjectModel.Common.ParseBase64(DirectCast(rawData.CloneNode(True), Xml.XmlDocument))
               For Each child As Xml.XmlNode In rawData.ChildNodes
                  Dim lName As String = CMISObjectModel.Common.GetNodeNameWithoutPrefix(child).ToLowerInvariant
                  If lName.Equals("entry") Then
                     'Parse entry node
                     Return Syndication.CmisSyndicationItem.ParseEntry(child)
                  ElseIf lName.Equals("acl") Then
                     'Parse acl node
                     Using stream As New IO.StringReader(child.OuterXml)
                        Dim serializer As New XmlSerializer(GetType(Acl))
                        Return DirectCast(serializer.Deserialize(stream), Acl)
                     End Using
                  ElseIf lName.Equals("query") Then
                     'Parse query node
                     Using stream As New IO.StringReader(child.OuterXml)
                        Dim serializer As New XmlSerializer(GetType(Query))
                        Return DirectCast(serializer.Deserialize(stream), Query)
                     End Using
                  End If
               Next
            End If
         Catch ex As Exception
            'Log error
            Common.Log(ex)
         End Try
         Return Nothing
      End Function

      ''' <summary>
      ''' Returns a list of SyndicationLink that contains the current url.
      ''' </summary>
      ''' <param name="selfLinkType"></param>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Private Function GetBaseLinks(selfLinkType As String) As List(Of SyndicationLink)
         Dim links As New List(Of SyndicationLink)
         links.Add(CmisSyndicationFeed.GetSelfLink(Me.SelfLink, selfLinkType))
         Return links
      End Function

      ''' <summary>
      ''' Returns the first/next/previous/last link for navigation. Navigation is necessary if the data provider only returns a part of a cmis list.
      ''' </summary>
      ''' <param name="itemsCount"></param>
      ''' <param name="pTotalItemCount"></param>
      ''' <param name="hasMoreItems"></param>
      ''' <param name="pCurrentSkipCount"></param>
      ''' <param name="pCurrentMaxItems"></param>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Private Function GetNavigationLinks(itemsCount As Integer, pTotalItemCount As Integer?, hasMoreItems As Boolean, pCurrentSkipCount As Integer?, pCurrentMaxItems As Integer?) As List(Of SyndicationLink)

         'If the requested list is complete no navigation is needed.
         If Not hasMoreItems AndAlso Not pCurrentMaxItems.HasValue Then
            Return New List(Of SyndicationLink)
         End If

         Dim totalItemCount As Integer = 0

         'If the data provider specifies a totalCount it is used. Otherwise Integer.MaxValue is assumed.
         If Not pTotalItemCount.HasValue AndAlso hasMoreItems Then
            totalItemCount = Integer.MaxValue
         Else
            totalItemCount = pTotalItemCount.Value
         End If

         'Number of skiped objects. Default: 0
         Dim currentSkipCount As Integer = If(pCurrentSkipCount.HasValue, pCurrentSkipCount.Value, 0)
         'Number of requested items. If maxItems is not specified by the client the number of returned objects is used.
         Dim currentMaxItemsCount As Integer = If(pCurrentMaxItems.HasValue, pCurrentMaxItems.Value, itemsCount)



         Dim oldParams As Specialized.NameValueCollection = System.Web.HttpUtility.ParseQueryString(SelfLink.Query)
         Dim newParams As New List(Of String)
         'Removes the parameter maxitems and skipcount from the requested url.
         For Each p As String In oldParams.AllKeys
            Dim lp As String = p.ToLowerInvariant
            If Not lp.Equals("maxitems") AndAlso Not lp.Equals("skipcount") Then
               newParams.Add(lp & "=" & System.Web.HttpUtility.UrlEncode(oldParams(p)))
            End If
         Next

         'Adds maxitems ans skipcount parameter (with placeholder) to the querystring 
         newParams.Add("maxItems={maxItems}")
         newParams.Add("skipCount={skipCount}")
         Dim absolutePath As String = SelfLink.AbsolutePath
         If Not absolutePath.EndsWith("/") Then
            absolutePath = absolutePath & "/"
         End If
         'Builds uri if the new query string.
         Dim baseLink As String = String.Format("{0}{1}{2}{3}?{4}", SelfLink.Scheme, Uri.SchemeDelimiter, SelfLink.Authority, absolutePath, String.Join("&", newParams))

         Dim retVal As New List(Of SyndicationLink)

         'Firstlink: 
         'skipcount is 0 
         'maxItems is the calculated value in 'currentMaxItems'
         Dim firstLink As String = baseLink.Replace("{skipCount}", "0").Replace("{maxItems}", currentMaxItemsCount.ToString)
         retVal.Add(CmisSyndicationFeed.GetFirstLink(New Uri(firstLink)))

         'NextLink: 
         'The newSkipCount is the currentSkipCount + the actually returned objects.
         'maxItems is the calculated value in 'currentMaxItems'
         Dim newSkipCount As Integer = currentSkipCount + itemsCount
         If newSkipCount < totalItemCount Then
            Dim nextLink As String = baseLink.Replace("{skipCount}", newSkipCount.ToString).Replace("{maxItems}", currentMaxItemsCount.ToString)
            retVal.Add(CmisSyndicationFeed.GetNextLink(New Uri(nextLink)))
         End If

         'PreviousLink:
         'Can only be set if the currentSkipCount is greater 0.
         'The prevSkipCount is the currentSkipCount minus the currentMaxItems
         'maxItems is the calculated value in 'currentMaxItems'
         If currentSkipCount > 0 Then
            Dim prevSkipCount As Integer = currentSkipCount - currentMaxItemsCount
            If prevSkipCount < 0 Then
               prevSkipCount = 0
            End If
            Dim prevLink As String = baseLink.Replace("{skipCount}", prevSkipCount.ToString).Replace("{maxItems}", currentMaxItemsCount.ToString)
            retVal.Add(CmisSyndicationFeed.GetPreviousLink(New Uri(prevLink)))
         End If
         'Lastlink:
         'Can only be set if the data provider has specified the total count.
         'lastCount is the totalItemCount minus the currentMaxItemsCount.
         'maxItems is the calculated value in 'currentMaxItems'
         If pTotalItemCount.HasValue Then
            Dim lastCount As Integer = totalItemCount - currentMaxItemsCount
            If lastCount < 0 Then
               lastCount = 0
            End If
            Dim lastLink As String = baseLink.Replace("{skipCount}", lastCount.ToString).Replace("{maxItems}", currentMaxItemsCount.ToString)
            retVal.Add(CmisSyndicationFeed.GetLastLink(New Uri(lastLink)))
         End If

         Return retVal

      End Function

      Private _ProviderManagerInstance As ProviderManager
      ''' <summary>
      ''' Creates a new Instance of the ProviderManager. The ProviderManager has an instance of the data provider 
      ''' </summary>
      ''' <value></value>
      ''' <returns></returns>
      ''' <remarks></remarks>
      Private ReadOnly Property ProviderManagerInstance As ProviderManager
         Get

            If _ProviderManagerInstance Is Nothing Then
               _ProviderManagerInstance = New ProviderManager


               If System.ServiceModel.ServiceSecurityContext.Current Is Nothing Then
                  _ProviderManagerInstance.Provider.Init("")
               Else
                  Dim identity As System.Security.Principal.IIdentity = System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity
                  _ProviderManagerInstance.Provider.Init(identity.Name)
               End If


            End If

            Return _ProviderManagerInstance
         End Get
      End Property
#End Region


     
   End Class
End Namespace